package com.shuda.business.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuda.business.crm.dto.CustomerFollowUpDTO;
import com.shuda.business.crm.dto.CustomerFollowUpQueryDTO;
import com.shuda.business.crm.entity.CustomerFollowUpEntity;
import com.shuda.business.crm.mapper.CustomerFollowUpMapper;
import com.shuda.business.crm.service.CustomerFollowUpService;
import com.shuda.common.dto.PageDTO;
import com.shuda.common.utils.PageResult;
import com.shuda.common.core.exception.BusinessException;
import com.shuda.common.security.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户跟进服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerFollowUpServiceImpl extends ServiceImpl<CustomerFollowUpMapper, CustomerFollowUpEntity> 
        implements CustomerFollowUpService {

    private final CustomerFollowUpMapper customerFollowUpMapper;

    @Override
    public PageResult<CustomerFollowUpDTO> getFollowUpPage(PageDTO pageDTO, CustomerFollowUpQueryDTO queryDTO) {
        LambdaQueryWrapper<CustomerFollowUpEntity> wrapper = new LambdaQueryWrapper<>();
        
        if (queryDTO.getCustomerId() != null) {
            wrapper.eq(CustomerFollowUpEntity::getCustomerId, queryDTO.getCustomerId());
        }
        
        if (queryDTO.getFollowUpType() != null) {
            wrapper.eq(CustomerFollowUpEntity::getFollowUpType, queryDTO.getFollowUpType());
        }
        
        if (queryDTO.getFollowUpStatus() != null) {
            wrapper.eq(CustomerFollowUpEntity::getFollowUpStatus, queryDTO.getFollowUpStatus());
        }
        
        if (queryDTO.getAssignedUserId() != null) {
            wrapper.eq(CustomerFollowUpEntity::getAssignedUserId, queryDTO.getAssignedUserId());
        }
        
        if (queryDTO.getStartTime() != null && queryDTO.getEndTime() != null) {
            wrapper.between(CustomerFollowUpEntity::getFollowUpTime, queryDTO.getStartTime(), queryDTO.getEndTime());
        }
        
        wrapper.orderByDesc(CustomerFollowUpEntity::getFollowUpTime);
        
        IPage<CustomerFollowUpEntity> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        IPage<CustomerFollowUpEntity> resultPage = this.page(page, wrapper);
        
        List<CustomerFollowUpDTO> dtoList = resultPage.getRecords().stream().map(entity -> {
            CustomerFollowUpDTO dto = new CustomerFollowUpDTO();
            dto.setId(entity.getId());
            dto.setCustomerId(entity.getCustomerId());
            dto.setCustomerName(entity.getCustomerName());
            dto.setFollowUpType(entity.getFollowUpType());
            dto.setFollowUpStatus(entity.getFollowUpStatus());
            dto.setFollowUpContent(entity.getFollowUpContent());
            dto.setFollowUpResult(entity.getFollowUpResult());
            dto.setNextFollowUpTime(entity.getNextFollowUpTime());
            dto.setAssignedUserId(entity.getAssignedUserId());
            dto.setAssignedUserName(entity.getAssignedUserName());
            dto.setFollowUpTime(entity.getFollowUpTime());
            dto.setCreateTime(entity.getCreateTime());
            dto.setUpdateTime(entity.getUpdateTime());
            return dto;
        }).collect(Collectors.toList());
        
        return new PageResult<>(dtoList, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
    }

    @Override
    public CustomerFollowUpDTO getFollowUpById(Long id) {
        CustomerFollowUpEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("跟进记录不存在");
        }
        
        CustomerFollowUpDTO dto = new CustomerFollowUpDTO();
        dto.setId(entity.getId());
        dto.setCustomerId(entity.getCustomerId());
        dto.setCustomerName(entity.getCustomerName());
        dto.setFollowUpType(entity.getFollowUpType());
        dto.setFollowUpStatus(entity.getFollowUpStatus());
        dto.setFollowUpContent(entity.getFollowUpContent());
        dto.setFollowUpResult(entity.getFollowUpResult());
        dto.setNextFollowUpTime(entity.getNextFollowUpTime());
        dto.setAssignedUserId(entity.getAssignedUserId());
        dto.setAssignedUserName(entity.getAssignedUserName());
        dto.setFollowUpTime(entity.getFollowUpTime());
        dto.setCreateTime(entity.getCreateTime());
        dto.setUpdateTime(entity.getUpdateTime());
        
        return dto;
    }

    @Override
    @Transactional
    public CustomerFollowUpDTO createFollowUp(CustomerFollowUpDTO followUpDTO) {
        CustomerFollowUpEntity entity = new CustomerFollowUpEntity();
        entity.setCustomerId(followUpDTO.getCustomerId());
        entity.setCustomerName(followUpDTO.getCustomerName());
        entity.setFollowUpType(followUpDTO.getFollowUpType());
        entity.setFollowUpStatus(followUpDTO.getFollowUpStatus());
        entity.setFollowUpContent(followUpDTO.getFollowUpContent());
        entity.setFollowUpResult(followUpDTO.getFollowUpResult());
        entity.setNextFollowUpTime(followUpDTO.getNextFollowUpTime());
        entity.setAssignedUserId(followUpDTO.getAssignedUserId());
        entity.setAssignedUserName(followUpDTO.getAssignedUserName());
        entity.setFollowUpTime(followUpDTO.getFollowUpTime());
        entity.setCreateBy(SecurityUtils.getCurrentUsername());
        
        this.save(entity);
        
        followUpDTO.setId(entity.getId());
        followUpDTO.setCreateTime(entity.getCreateTime());
        followUpDTO.setUpdateTime(entity.getUpdateTime());
        
        return followUpDTO;
    }

    @Override
    @Transactional
    public CustomerFollowUpDTO updateFollowUp(Long id, CustomerFollowUpDTO followUpDTO) {
        CustomerFollowUpEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("跟进记录不存在");
        }
        
        entity.setFollowUpType(followUpDTO.getFollowUpType());
        entity.setFollowUpStatus(followUpDTO.getFollowUpStatus());
        entity.setFollowUpContent(followUpDTO.getFollowUpContent());
        entity.setFollowUpResult(followUpDTO.getFollowUpResult());
        entity.setNextFollowUpTime(followUpDTO.getNextFollowUpTime());
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        
        this.updateById(entity);
        
        followUpDTO.setId(entity.getId());
        followUpDTO.setUpdateTime(entity.getUpdateTime());
        
        return followUpDTO;
    }

    @Override
    @Transactional
    public Boolean deleteFollowUp(Long id) {
        CustomerFollowUpEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("跟进记录不存在");
        }
        
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        this.updateById(entity);
        
        return this.removeById(id);
    }

    @Override
    public PageResult<CustomerFollowUpDTO> getCustomerFollowUps(PageDTO pageDTO, Long customerId) {
        LambdaQueryWrapper<CustomerFollowUpEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerFollowUpEntity::getCustomerId, customerId)
               .orderByDesc(CustomerFollowUpEntity::getFollowUpTime);
        
        IPage<CustomerFollowUpEntity> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        IPage<CustomerFollowUpEntity> resultPage = this.page(page, wrapper);
        
        List<CustomerFollowUpDTO> dtoList = resultPage.getRecords().stream().map(entity -> {
            CustomerFollowUpDTO dto = new CustomerFollowUpDTO();
            dto.setId(entity.getId());
            dto.setCustomerId(entity.getCustomerId());
            dto.setCustomerName(entity.getCustomerName());
            dto.setFollowUpType(entity.getFollowUpType());
            dto.setFollowUpStatus(entity.getFollowUpStatus());
            dto.setFollowUpContent(entity.getFollowUpContent());
            dto.setFollowUpResult(entity.getFollowUpResult());
            dto.setNextFollowUpTime(entity.getNextFollowUpTime());
            dto.setAssignedUserId(entity.getAssignedUserId());
            dto.setAssignedUserName(entity.getAssignedUserName());
            dto.setFollowUpTime(entity.getFollowUpTime());
            dto.setCreateTime(entity.getCreateTime());
            dto.setUpdateTime(entity.getUpdateTime());
            return dto;
        }).collect(Collectors.toList());
        
        return new PageResult<>(dtoList, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
    }

    @Override
    public PageResult<CustomerFollowUpDTO> getMyFollowUps(PageDTO pageDTO) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        LambdaQueryWrapper<CustomerFollowUpEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerFollowUpEntity::getAssignedUserId, currentUserId)
               .orderByDesc(CustomerFollowUpEntity::getFollowUpTime);
        
        IPage<CustomerFollowUpEntity> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        IPage<CustomerFollowUpEntity> resultPage = this.page(page, wrapper);
        
        List<CustomerFollowUpDTO> dtoList = resultPage.getRecords().stream().map(entity -> {
            CustomerFollowUpDTO dto = new CustomerFollowUpDTO();
            dto.setId(entity.getId());
            dto.setCustomerId(entity.getCustomerId());
            dto.setCustomerName(entity.getCustomerName());
            dto.setFollowUpType(entity.getFollowUpType());
            dto.setFollowUpStatus(entity.getFollowUpStatus());
            dto.setFollowUpContent(entity.getFollowUpContent());
            dto.setFollowUpResult(entity.getFollowUpResult());
            dto.setNextFollowUpTime(entity.getNextFollowUpTime());
            dto.setAssignedUserId(entity.getAssignedUserId());
            dto.setAssignedUserName(entity.getAssignedUserName());
            dto.setFollowUpTime(entity.getFollowUpTime());
            dto.setCreateTime(entity.getCreateTime());
            dto.setUpdateTime(entity.getUpdateTime());
            return dto;
        }).collect(Collectors.toList());
        
        return new PageResult<>(dtoList, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
    }

    @Override
    public List<CustomerFollowUpDTO> getPendingFollowUps() {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        LocalDateTime now = LocalDateTime.now();
        
        LambdaQueryWrapper<CustomerFollowUpEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerFollowUpEntity::getAssignedUserId, currentUserId)
               .eq(CustomerFollowUpEntity::getFollowUpStatus, "pending")
               .le(CustomerFollowUpEntity::getNextFollowUpTime, now)
               .orderByAsc(CustomerFollowUpEntity::getNextFollowUpTime);
        
        List<CustomerFollowUpEntity> entities = this.list(wrapper);
        
        return entities.stream().map(entity -> {
            CustomerFollowUpDTO dto = new CustomerFollowUpDTO();
            dto.setId(entity.getId());
            dto.setCustomerId(entity.getCustomerId());
            dto.setCustomerName(entity.getCustomerName());
            dto.setFollowUpType(entity.getFollowUpType());
            dto.setFollowUpStatus(entity.getFollowUpStatus());
            dto.setFollowUpContent(entity.getFollowUpContent());
            dto.setFollowUpResult(entity.getFollowUpResult());
            dto.setNextFollowUpTime(entity.getNextFollowUpTime());
            dto.setAssignedUserId(entity.getAssignedUserId());
            dto.setAssignedUserName(entity.getAssignedUserName());
            dto.setFollowUpTime(entity.getFollowUpTime());
            dto.setCreateTime(entity.getCreateTime());
            dto.setUpdateTime(entity.getUpdateTime());
            return dto;
        }).collect(Collectors.toList());
    }
}